home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 8
/
Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso
/
Aminet
/
comm
/
tcp
/
socklink100.lha
/
socklink
/
socklink.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-01
|
12KB
|
347 lines
/*****************************************************************************\
* *
* socklink.c -- links a socket to stdio *
* *
* Copyright (c) 1995 by Sam Yee. *
* Source freely redistributable in unmodified form. *
* *
* $ Author: Sam Yee (samy@sfu.ca) $ *
* $ Project: socklink $ *
* $ Date Started: May 17, 1995 $ *
* $ Version: 1.00 (1.9.95) $ *
* *
* History: *
* Ver. YY/MM/DD Who Modifications *
* --------------------------------------------------------------------------- *
* 1.00 95/09/01 Sam Yee Original release *
* *
\*****************************************************************************/
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <devices/timer.h>
#include <dos/dos.h>
#include <exec/types.h>
#include <exec/libraries.h>
#include <exec/execbase.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <errno.h>
#include <stdlib.h>
#ifdef _AMITCP
#include <bsdsocket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <syslog.h>
#include <amitcp/socketbasetags.h>
#include <string.h>
#else
#include <proto/all.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <ss/socket.h>
#define WaitSelect selectwait
#define CloseSocket s_close
#define IoctlSocket s_ioctl
#endif /* _AMITCP */
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif /* TRUE */
#define VERSION "1.00"
#ifndef BOOL
#define short BOOL
#endif /* BOOL */
#define RAWIN_RUNTIME
#include "RawIN.h"
/*****************************************************************************/
const char version[] = "\0$VER: SockLink/"
#ifdef _AMITCP
"AmiTCP"
#else
"AS225r2"
#endif /* _AMITCP */
" "VERSION" (1.9.95)";
extern struct DosLibrary *DOSBase;
#ifdef _AMITCP
extern STRPTR _ProgramName; /* provided by SAS/C startup */
struct Library *SocketBase;
int h_errno = 0;
#else
struct Library *SockBase;
#endif /* !_AMITCP */
/*****************************************************************************/
/* prototypes */
void __regargs __chkabort(void); /* disable SAS/C ^C checking */
void __regargs __chkabort(){}
void __regargs _CXBRK(void);
void __regargs _CXBRK(){}
int connect_server(char *prog_name, char *host_name, int port);
int init_socklib(void);
void cleanup_socklib(void);
/*****************************************************************************/
int
main(int argc,
char *argv[])
{
struct Library *RawINBase;
struct Line *line;
BOOL sock_writing = FALSE;
char *prog_name,
sockout_buf[256],
stdout_buf[256];
int sock,
select_return,
read_len,
break_count = 0,
wait_seconds = 0,
rc = 10;
fd_set r_fds,
w_fds,
readmask,
writemask;
u_long wait_mask,
return_mask;
prog_name = FilePart(argv[0]);
if (argc < 3)
Printf("Usage: %s <host> <port> [start-delay-seconds]\n",prog_name);
else
{
if (!init_socklib())
{
if ((sock = connect_server(prog_name,argv[1],atoi(argv[2]))) >= 0)
{
if (RawINBase = OpenLibrary(RAWIN_NAME,0))
{
if (line = RI_AllocLine(2L,2L))
{
rc = 0;
Printf("SockLink " VERSION " (" __DATE__ " " __TIME__ ") -- links stdio to socket\n"
"Copyright (c) by Sam Yee (samy@sfu.ca). Freely distributable.\n"
"Press ^C^C^C (3 Control-C's) to terminate.\n\n"
"Connected to %s at port %ld.\n"
,argv[1],atoi(argv[2]));
if (argc > 3)
{
struct timeval tv;
wait_seconds = atol(argv[3]);
Printf("Linking stdio to socket in %ld seconds.\n\n",wait_seconds);
#ifdef _AMITCP
tv.tv_sec = wait_seconds;
tv.tv_usec = 0;
#else
tv.tv_secs = wait_seconds;
tv.tv_micro = 0;
#endif /* _AMITCP */
select(0,NULL,NULL,NULL,&tv);
}
else
Printf("\n");
wait_mask = SIGBREAKF_CTRL_C |
(1L << line->ReadReplyPort->mp_SigBit);
RI_SendReadRequest(line); /* send a request to the input handler */
FD_SET(sock,&r_fds);
FD_SET(sock,&w_fds);
/* keeping going until something goes bad */
while (!(line->flags & (LNF_EOF|LNF_BREAKC|LNF_READERROR|LNF_WRITEERROR)))
{
return_mask = wait_mask;
readmask = r_fds;
writemask = w_fds;
select_return = WaitSelect(sock+1,&readmask,
sock_writing ? &writemask : NULL,
NULL,NULL,&return_mask);
if ((select_return < 0) && (errno != EINTR))
{
Printf("\n\n%s: select returns %ld; errno=%ld\n",
prog_name,select_return,errno);
break;
}
if (FD_ISSET(sock,&readmask))
{
/* wait for a write to finish if needed */
RI_WaitWrite(line);
if ((read_len = recv(sock,stdout_buf,sizeof(stdout_buf),0)) > 0)
RI_SendWriteRequest(line,stdout_buf,read_len);
else
{
Printf("\n\nEOF Connection closed by foreign host.\n");
break;
}
}
if (sock_writing)
{
if (FD_ISSET(sock,&writemask))
sock_writing = FALSE;
}
/* we can't read from stdin if we are already writing to socket */
if (!sock_writing)
{
if ((read_len = RI_GetBlock(line,FALSE,FALSE,sockout_buf,
sizeof(sockout_buf))) > 0L)
{
if (sockout_buf[0] == 0x03) /* ^C? */
break_count++;
else
break_count = 0;
send(sock,sockout_buf,read_len,0);
sock_writing = TRUE;
if (break_count != 3)
RI_SendReadRequest(line);
else
break; /* ^C^C^C quits */
}
}
if (return_mask & SIGBREAKF_CTRL_C)
break;
}
RI_FreeLine(line);
}
CloseLibrary(RawINBase);
}
CloseSocket(sock);
}
cleanup_socklib();
}
else
Printf("%s: TCP/IP stack not running\n",prog_name);
}
return(rc);
}
/*****************************************************************************/
/* connects to a host at a specifc port */
int /* socket descriptor if connection succeeded, else -1 */
connect_server(char *prog_name,
char *host_name,
int port)
{
struct in_addr defaddr;
struct hostent *hp;
struct sockaddr_in sin;
int sock;
long onoff = 1;
/* lookup the IP address of a host */
if (hp = gethostbyname(host_name))
{
sin.sin_family = hp->h_addrtype;
memcpy(&sin.sin_addr,hp->h_addr,hp->h_length);
}
else
{
if ((defaddr.s_addr = inet_addr(host_name)) == -1)
{
Printf("%s: unknown host: %s\n",prog_name,host_name);
return(-1);
}
sin.sin_family = PF_INET;
memcpy(&sin.sin_addr,&defaddr,sizeof(struct in_addr));
}
sin.sin_port = htons(port);
/* open a socket */
if ((sock = socket(AF_INET,SOCK_STREAM,0)) >= 0)
{
/* connect sock to host */
if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) == -1)
{
Printf("%s: connection refused: errno=%ld\n",prog_name,errno);
CloseSocket(sock);
sock = -1;
}
else
IoctlSocket(sock,FIOASYNC,(caddr_t)&onoff);
}
return(sock);
}
/*****************************************************************************/
/* opens socket library, or non-zero for error */
int
init_socklib(void)
{
#ifdef _AMITCP
if (SocketBase = OpenLibrary("bsdsocket.library",0L))
{
if (!SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), &errno,
SBTM_SETVAL(SBTC_HERRNOLONGPTR), &h_errno,
SBTM_SETVAL(SBTC_LOGTAGPTR), _ProgramName,
TAG_END))
return(0);
CloseLibrary(SocketBase);
}
#else
if (SockBase = OpenLibrary("socket.library",0L))
{
setup_sockets(10,&errno);
return(0);
}
#endif /* _AMITCP */
return(-1);
}
/*****************************************************************************/
void
cleanup_socklib(void)
{
#ifdef _AMITCP
CloseLibrary(SocketBase);
#else
cleanup_sockets();
CloseLibrary(SockBase);
#endif /* _AMITCP */
}
/*****************************************************************************/
/* EOF socklink.c */